﻿using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using RedRiver.Framework.XtraCommon.Properties;

namespace RedRiver.Framework.XtraCommon.XtraControls{
    public class OpenFileButtonEdit : ButtonEdit{
        #region FileDialogType enum

        /// <summary>
        /// 
        /// </summary>
        public enum FileDialogType{
            /// <summary>
            /// 打开文件对话框
            /// </summary>
            OpenFileDialog,
            /// <summary>
            /// 保存文件对话框
            /// </summary>
            SaveFileDialog,
            /// <summary>
            /// 文件夹选择对话框
            /// </summary>
            FolderBrowserDialog
        }

        #endregion

        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private readonly IContainer _components;

        private CommonDialog _dialog;

        public OpenFileButtonEdit(IContainer components){
            _components = components;
            InitializeComponent();
            DialogType = FileDialogType.OpenFileDialog;
            InitButton();
        }

        public OpenFileButtonEdit(IContainer container, IContainer components){
            _components = components;
            container.Add(this);
            InitializeComponent();
            InitButton();
        }

        /// <summary>
        /// Gets or sets the file dialog box title
        /// </summary>
        /// <see cref="FileDialog.Title"/>
        [Localizable(true), Description("文件对话框标题"), DefaultValue(""), Category("Appearance")]
        public string Title{
            get;
            set;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="FileDialog.Filter"/>
        [Category("Behavior"), DefaultValue(""), Localizable(true), Description("文件对话框过滤条件")]
        public string Filter{
            get;
            set;
        }

        [Category("Behavior"), DefaultValue(FileDialogType.OpenFileDialog), Localizable(true), Description("文件对话框类型")]
        public FileDialogType DialogType{
            get;
            set;
        }

        [Category("Behavior"), DefaultValue(true), Localizable(true), Description("是否允许空值")]
        public bool AllowNull{
            get;
            set;
        }

        protected override void OnValidating(CancelEventArgs e){
            base.OnValidating(e);
            if ((!AllowNull) && (string.IsNullOrEmpty(Text))){
                e.Cancel = true;
                ErrorText = "不允许空值";
                return;
            }
            switch (DialogType){
                case FileDialogType.OpenFileDialog:
                    if (!File.Exists(Text)){
                        e.Cancel = true;
                        ErrorText = "指定文件不存在";
                    } else{
                        ErrorText = string.Empty;
                    }
                    break;
                case FileDialogType.FolderBrowserDialog:
                    if (!Directory.Exists(Text)){
                        e.Cancel = true;
                        ErrorText = "指定目录不存在";
                    } else{
                        ErrorText = string.Empty;
                    }
                    break;
            }
        }

        private void InitButton(){
            if (!DesignMode){
                Properties.CreateDefaultButton();
                if (Properties.Buttons.Count > 0){
                    Properties.Buttons[0].Image = Resources.Open;
                    Properties.Buttons[0].Kind = ButtonPredefines.Glyph;
                }
                ButtonClick += FileOpenButtonEdit_ButtonClick;
            }
        }

        private void FileOpenButtonEdit_ButtonClick(object sender, ButtonPressedEventArgs e){
            if (!Properties.Enabled || Properties.ReadOnly){
                return;
            }
            OpenDialog();
        }

        private void OpenDialog(){
            switch (DialogType){
                case FileDialogType.OpenFileDialog:
                    OpenFileDialog openFileDialog;
                    if ((_dialog == null) || (!(_dialog is OpenFileDialog))){
                        _dialog = new OpenFileDialog();
                        _dialog.Disposed += DialogDisposed;
                    }
                    openFileDialog = (OpenFileDialog) _dialog;
                    openFileDialog.Title = Title;
                    openFileDialog.Filter = Filter;
                    if (!string.IsNullOrEmpty(Text)){
                        openFileDialog.InitialDirectory = Path.GetDirectoryName(Text);
                        openFileDialog.FileName = Path.GetFileName(Text);
                    }
                    if (openFileDialog.ShowDialog(this) == DialogResult.OK){
                        EditValue = openFileDialog.FileName;
                    }
                    break;
                case FileDialogType.SaveFileDialog:

                    if ((_dialog == null) || (!(_dialog is SaveFileDialog))){
                        _dialog = new OpenFileDialog();
                        _dialog.Disposed += DialogDisposed;
                    }
                    var saveFileDialog = (SaveFileDialog) _dialog;
                    saveFileDialog.Title = Title;
                    saveFileDialog.Filter = Filter;
                    if (!string.IsNullOrEmpty(Text)){
                        saveFileDialog.InitialDirectory = Path.GetDirectoryName(Text);
                        saveFileDialog.FileName = Path.GetFileName(Text);
                    }
                    if (saveFileDialog.ShowDialog(this) == DialogResult.OK){
                        EditValue = saveFileDialog.FileName;
                    }
                    break;
                case FileDialogType.FolderBrowserDialog:
                    if ((_dialog == null) || (!(_dialog is FolderBrowserDialog))){
                        _dialog = new FolderBrowserDialog();
                        _dialog.Disposed += DialogDisposed;
                    }
                    var folderBrowserDialog = (FolderBrowserDialog) _dialog;
                    folderBrowserDialog.Description = Title;
                    if (!string.IsNullOrEmpty(Text)){
                        folderBrowserDialog.SelectedPath = Path.GetDirectoryName(Text);
                    }
                    if (folderBrowserDialog.ShowDialog(this) == DialogResult.OK){
                        EditValue = folderBrowserDialog.SelectedPath;
                    }
                    break;
            }
        }

        private void DialogDisposed(object sender, EventArgs e){
            _dialog = null;
        }

        /// <summary> 
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
        protected override void Dispose(bool disposing){
            if (disposing && (_components != null)){
                _components.Dispose();
            }
            if (_dialog != null){
                _dialog.Dispose();
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent(){}
    }
}